package vn.edu.hut.soict.translate.transform;

import java.util.LinkedList;
import java.util.List;

import vn.edu.hut.soict.lienkate.parser.Connection;
import vn.edu.hut.soict.translate.transform.utils.GrammaticalConstant;
import vn.edu.hut.soict.translate.transform.utils.GrammaticalNumber;
import vn.edu.hut.soict.translate.transform.utils.VerbTransformUtils;

public class DeletionTransformer extends Transformer {

	public DeletionTransformer(InnerTransformer transformer) {
		super(transformer);
	}

	/*
	 * Delete a token in destination token list.
	 * @param i the position of the token
	 */
	public void delete(int i) {
		if (sourceLinkage == null || destinationLinkage == null) {
			deleteFromDestination(i);
			return;
		}

		for (Connection connection : sourceLinkage.getLink().get(i)) {
			if (!deletedConnections.contains(connection) && leftToRightDelete(i, connection)) {
				deletedConnections.add(connection);
				return;
			}
		}

		for (int j = 0; j < i; j++) {
			LinkedList<Connection> links = sourceLinkage.getLink().get(j);
			for (Connection connection : links) {
				if (i == connection.right()) {
					if (!deletedConnections.contains(connection) && rightToLeftDelete(i, connection)) {
						deletedConnections.add(connection);
						return;
					}
				}
			}
		}
		deleteFromDestination(i);
	}

	private boolean leftToRightDelete(int i, Connection connection) {
		if (deleteDeterminer(i, connection)) {
			return true;
		}
		if (deleteTenseOfVerb(i, connection)) {
			return true;
		}
		return false;
	}

	private boolean rightToLeftDelete(int j, Connection connection) {
		String type = connection.type();
		String connectedWord = sourceTokenList.get(j);
		int i = connection.right();
		String baseWord = sourceTokenList.get(i);
		return false;
	}

	private boolean deleteDeterminer(int i, Connection connection) {
		String type = connection.type();
		int j = connection.right();
		List<Integer> indexes = alignmentParser.destinationIndexesAlignWith(j);

		if (indexes == null) {
			return false;
		}
		else if (indexes.size() > 1) {
			System.err.println("Not supported yet");
		}
		int index = indexes.get(0);

		if (type.startsWith("TDT1") || type.startsWith("TDT2") || type.startsWith("ST_DT")) {
			if ((type.length() >= 5 && type.charAt(4) == 'p') || type.equals("ST_DTu")) {
				if (findRightConnection(sourceLinkage, j, "TDT1p", connection) > 0 && findRightConnection(sourceLinkage, j, "TDT2p", connection) > 0 && findRightConnection(sourceLinkage, j, "ST_DTpu", connection) > 0 && findRightConnection(sourceLinkage, j, "ST_DTpd", connection) > 0) {
					String destinationWord = destinationTokenList.get(index);
					destinationWord = GrammaticalNumber.nounDecline(destinationWord, GrammaticalConstant.SINGULAR);
					destinationTokenList.set(index, destinationWord);
				}
				if (type.length() < 6 || type.charAt(5) != 'k') {
					deleteFromDestination(i);
				}
				return true;
			}
		}

		return false;
	}

	private boolean deleteTenseOfVerb(int i, Connection connection) {
		String type = connection.type();
		int j = connection.right();
		List<Integer> indexes = alignmentParser.destinationIndexesAlignWith(j);

		if (indexes == null) {
			return false;
		}
		else if (indexes.size() > 1) {
			System.err.println("Not supported yet");
		}

		if (type.startsWith("TĐT3") && type.length() >= 5) {
			int verbIndex = indexes.get(0);
			int subjectIndex = -1;
			String verb = destinationTokenList.get(verbIndex);
			char tense = type.charAt(4);
			switch (tense) {
				case 'q':
					subjectIndex = findRightConnection(destinationLinkage, verbIndex, "S", null);
					break;
				case 'c':
					int beIndex = findRightConnection(destinationLinkage, verbIndex, "Pg", null);
					deleteFromDestination(beIndex);
					subjectIndex = findRightConnection(destinationLinkage, beIndex, "S", null);
					break;
				case 't':
					subjectIndex = findRightConnection(destinationLinkage, i, "S", null);
					break;
				case 'h':
					int haveIndex = alignmentParser.destinationIndexesAlignWith(i).get(0);
					subjectIndex = findRightConnection(destinationLinkage, haveIndex, "S", null);
					break;
				case 'g':
					int goingIndex = alignmentParser.destinationIndexesAlignWith(i).get(0);
					beIndex = findRightConnection(destinationLinkage, goingIndex, "Pg", null);
					deleteFromDestination(beIndex);
					subjectIndex = findRightConnection(destinationLinkage, beIndex, "S", null);
					break;
			}

			String subject = destinationTokenList.get(subjectIndex);
			GrammaticalConstant numberSubject = GrammaticalNumber.nounOrPronounNumber(subject);
			if (!subject.equalsIgnoreCase("I") && numberSubject == GrammaticalConstant.SINGULAR) {
				verb = VerbTransformUtils.conjugate(verb, GrammaticalConstant.PRESENT_SIMPLE_WITH_SINGULAR);
			}
			else {
				verb = VerbTransformUtils.conjugate(verb, GrammaticalConstant.BARE);
				if (verb.equalsIgnoreCase("be")) {
					verb = "are";
				}
			}
			destinationTokenList.set(verbIndex, verb);
			if (type.length() < 6 || type.charAt(5) != 'k') {
				deleteFromDestination(i);
			}
			return true;
		}

		if (type.startsWith("TTT3") && type.length() >= 5) {
			int subjectIndex = -1;
			int beIndex = -1;
			char tense = type.charAt(4);
			switch (tense) {
				case 'q':
					beIndex = i;
					subjectIndex = findRightConnection(destinationLinkage, beIndex, "S", null);
					break;
				case 't':
					beIndex = findLeftConnection(destinationLinkage, i, "I", null);
					subjectIndex = findRightConnection(destinationLinkage, i, "S", null);
					break;
				case 'h':
					beIndex = findLeftConnection(destinationLinkage, i, "PP", null);
					subjectIndex = findRightConnection(destinationLinkage, i, "S", null);
					break;
			}

			String subject = destinationTokenList.get(subjectIndex);
			String be = destinationTokenList.get(beIndex);
			GrammaticalConstant numberSubject = GrammaticalNumber.nounOrPronounNumber(subject);
			if (subject.equalsIgnoreCase("I")) {
				be = "am";
			}
			else if (numberSubject == GrammaticalConstant.SINGULAR) {
				be = VerbTransformUtils.conjugate(be, GrammaticalConstant.PRESENT_SIMPLE_WITH_SINGULAR);
			}
			else {
				be = VerbTransformUtils.conjugate(be, GrammaticalConstant.BARE);
				if (subject.equalsIgnoreCase("be")) {
					be = "are";
				}
			}
			destinationTokenList.set(beIndex, be);
			if (type.length() < 6 || type.charAt(5) != 'k') {
				deleteFromDestination(i);
			}
			return true;
		}

		return false;
	}

	private void deleteFromDestination(int i) {
		List<Integer> deletedIndexes = alignmentParser.destinationIndexesAlignWith(i);
		for (int j : deletedIndexes) {
			destinationTokenList.set(j, "");
		}
	}

}
